﻿using System;
using System.Web.Http;
using System.IO;
using System.Web;
using System.Text;
using System.Collections;
using YiYiTong.Rocket.Helper;
using YiYiTong.Rocket.Model;
using YiYiTong.Rocket.Business;
using System.Net.Http;
using System.Collections.Generic;
using YiYiTong.Rocket.Model.Model;

namespace YiYiTong.Rocket.Api.Controllers
{
    public class GateWayController : ApiController
    {
        /// <summary>
        /// api请求统一入口
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public HttpResponseMessage ApiPost()
        {
            ApiServiceContext apiContext = new ApiServiceContext();
            ApiHttpResponse apiResp = new ApiHttpResponse();
            apiContext.apiHttpResp = apiResp;
            try
            {
                //1. 获取post请求流
                Stream stream = HttpContext.Current.Request.InputStream;
                if (stream == null || stream.Length == 0)
                {
                    apiResp.retCode = ResultEnum.NoData;
                    apiResp.message = "无请求数据";
                    apiContext.apiHttpResp = apiResp;
                    return apiContext.ReturnResp();
                }

                //接收post流转换为字符串
                byte[] buffer = new byte[stream.Length];
                stream.Read(buffer, 0, buffer.Length);
                string postdata = Encoding.UTF8.GetString(buffer);
                LogHelper.Info("收到请求" + postdata);

                //2. 解析请求数据
                ApiHttpRequest apiReq = JsonHelper.Deserialize<ApiHttpRequest>(postdata);
                apiReq.data = Utils.ConvertToBase64Str(apiReq.data);

                //3. 检查判断通用参数
                if (string.IsNullOrEmpty(apiReq.merNo) || string.IsNullOrEmpty(apiReq.service) || string.IsNullOrEmpty(apiReq.sign) || string.IsNullOrEmpty(apiReq.machineCode)
                || string.IsNullOrEmpty(apiReq.timeStamp) || string.IsNullOrEmpty(apiReq.channel) || string.IsNullOrEmpty(apiReq.version))
                {
                    apiResp.retCode = ResultEnum.ParamError;
                    apiResp.message = "缺少参数";
                    apiContext.apiHttpResp = apiResp;
                    return apiContext.ReturnResp();
                }

                //验证时间戳是否有效&是否重复提交请求
                int intStamp = ConvertHelper.ConvertTo<int>(apiReq.timeStamp, 0);
                if (!Utils.CheckTimeStamp(intStamp, ConfigHelper.AppSetting<int>("TimeValid", 0)))
                {
                    apiResp.retCode = ResultEnum.TimeError;
                    apiResp.message = "手机时间异常，请到系统时间设置，将其设为最新";
                    apiContext.apiHttpResp = apiResp;
                    return apiContext.ReturnResp();
                }

                if (!Utils.CheckDoubleSubmit(apiReq.sign))
                {
                    apiResp.retCode = ResultEnum.DoubleSubmitError;
                    apiResp.message = "请求已失效，请重新提交";
                    apiContext.apiHttpResp = apiResp;
                    return apiContext.ReturnResp();
                }

                //检查data
                if (!OAuthBiz.Instance.CheckNoArgumentApi(apiReq.service) && string.IsNullOrEmpty(apiReq.data))
                {
                    apiResp.retCode = ResultEnum.ParamError;
                    apiResp.message = "data请求数据为空";
                    apiContext.apiHttpResp = apiResp;
                    return apiContext.ReturnResp();
                }

                //检查商户信息
                MerchantModel merchant = MerchantBiz.Instance.GetMerchant(apiReq.merNo);
                if (merchant == null)
                {
                    apiResp.retCode = ResultEnum.ParamError;
                    apiResp.message = "商户非法";
                    apiContext.apiHttpResp = apiResp;
                    return apiContext.ReturnResp();
                }

                if (merchant.merStatus != (int)MerchantEnum.AuditOK)
                {
                    apiResp.retCode = ResultEnum.MerchantError;
                    apiResp.message = "商户异常";
                    apiContext.apiHttpResp = apiResp;
                    return apiContext.ReturnResp();
                }
                apiContext.merKey = merchant.merKey;

                //检查token
                long userId = 0;
                if (!OAuthBiz.Instance.CheckToken(apiReq.service, apiReq.token, out userId))
                {
                    apiResp.retCode = ResultEnum.TokenError;
                    apiResp.message = "请重新登录";
                    apiContext.apiHttpResp = apiResp;
                    return apiContext.ReturnResp();
                }
                //当前登陆用户ID
                apiContext.CurrUserId = userId;



                ///设置了部分接口不需要签名校验
                if (!OAuthBiz.Instance.CheckNoSignApi(apiReq.service))
                {
                    //4. md5签名验证
                    Hashtable ht = ModelHandler<ApiHttpRequest>.TransforClass(apiReq);
                    if (!Utils.CheckSign(ht, merchant.merKey))
                    {
                        apiResp.retCode = ResultEnum.SignError;
                        apiResp.message = "请重新提交";
                        apiContext.apiHttpResp = apiResp;
                        return apiContext.ReturnResp();
                    }
                }
                apiContext.decData = Utils.DecodeBase64(apiReq.data);

                //发布消息到订阅中心
                SessionModel sessionModel = new SessionModel
                {
                    dateTime = DateTime.Now,
                    httpRequest = apiReq,
                    ip = HttpContext.Current.Request.UserHostAddress,
                    uid = userId
                };
                sessionModel.httpRequest.data = apiContext.decData;
                RedisService.PublishMessage("userrequestchannel", JsonHelper.Serialize(sessionModel));

                LogHelper.Info($"请求数据：{apiReq.service}--{apiContext.decData}");
                //5. 执行方法
                var action = DelegateFactory.GetDoAction(apiReq.service);
                if (action == null)
                {
                    apiResp.retCode = ResultEnum.NoService;
                    apiResp.message = "接口不存在";
                    apiContext.apiHttpResp = apiResp;
                    return apiContext.ReturnResp();
                }
                apiContext.apiHttpReq = apiReq;
                action(apiContext);
                return apiContext.ReturnResp();
            }
            catch (Exception ex)
            {
                LogHelper.Error("服务异常" + ex.Message + "\t\n" + ex.StackTrace);
                apiResp.retCode = ResultEnum.ServiceException;
                apiResp.message = "服务异常，请重试";
                apiContext.apiHttpResp = apiResp;
                return apiContext.ReturnResp();
            }
        }
    }
}
